//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#ifndef __GAS_H__
#define __GAS_H__

typedef struct SpaceBlock : DLinkNode
{
    UInt32            m_uBase;
    UInt32            m_cPages;

    SpaceBlock(UInt32 uBase, UInt32 cPages) :
        m_uBase(uBase),
        m_cPages(cPages)
    {
    }

}   SpaceBlock;

class GlobalAS
{
public:
    static inline void Initialize(UInt32 uBase, UInt32 uLimit);
    static inline UInt32 AllocB(UInt32 cBytes);
    static inline void FreeB(UInt32 uBase, UInt32 cBytes);

    static UInt32 AllocP(UInt32 cPages);
    static void FreeP(UInt32 uBase, UInt32 cPages);

    static UInt32 AllocFixedB(UInt32 uBase, UInt32 cBytes);
    static UInt32 AllocFixedP(UInt32 uBase, UInt32 cPages);


#ifndef _RELEASE
    static void View();
#endif // _RELEASE

private:
    static DLinkNode    s_freeList;
    static KMutex       s_listLock;
};

inline void GlobalAS::Initialize(UInt32 uBase, UInt32 uLimit)
{
    SpaceBlock * pBlock;

    pBlock = new SpaceBlock(uBase, (uLimit - uBase) >> PAGE_SHIFT);
    assert(pBlock != NULL);

    s_freeList.m_pPrev = s_freeList.m_pNext = pBlock;
    pBlock->m_pPrev = pBlock->m_pNext = &s_freeList;
}

inline UInt32 GlobalAS::AllocB(UInt32 cBytes)
{
    return GlobalAS::AllocP(B_TO_P(cBytes));
}

inline UInt32 GlobalAS::AllocFixedB(UInt32 uBase, UInt32 cBytes)
{
    return GlobalAS::AllocFixedP(uBase, B_TO_P(cBytes));
}

inline void GlobalAS::FreeB(UInt32 uBase, UInt32 cBytes)
{
    GlobalAS::FreeP(uBase, B_TO_P(cBytes));
}

#endif // __GAS_H__
